<?php

namespace App\Services\Aliyun\Video;

use App\Services\Aliyun\BaseService;
use App\Services\Configs\DefaultService;
use OSS\OssClient;
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
use AlibabaCloud\Vod\Vod;
use AlibabaCloud\Green\Green;

class VideoServices extends BaseService
{
    private $accessKeyId;
    private $accessKeySecret;
    private $callback;
    private $client;

    public function __construct()
    {
        $config = self::getConfig(DefaultService::ALI_OSS);
        $this->accessKeyId = $config['accessKeyId'];
        $this->accessKeySecret = $config['accessKeySecret'];
        $this->callback = $config['callback'] ?? '';
        $this->initVodClient();
    }

    /**
     * Notes: 初始化
     */
    public function initVodClient()
    {
        $regionId = 'cn-shanghai';  // 点播服务接入区域
        $this->client = AlibabaCloud::accessKeyClient($this->accessKeyId, $this->accessKeySecret)
            ->regionId($regionId)
            ->connectTimeout(1)
            ->timeout(3)
            ->asDefaultClient();
    }

    /**
     * Notes: 初始化点播
     * @param $uploadAuth
     * @param $uploadAddress
     */
    public function initOssClient($uploadAuth, $uploadAddress)
    {
        $ossClient = new OssClient($uploadAuth['AccessKeyId'], $uploadAuth['AccessKeySecret'], $uploadAddress['Endpoint'],
            false, $uploadAuth['SecurityToken']);
        $ossClient->setTimeout(86400 * 8);  //7  // 设置请求超时时间，单位秒，默认是5184000秒, 建议不要设置太小，如果上传文件很大，消耗的时间会比较长
        $ossClient->setConnectTimeout(100); //10 // 设置连接超时时间，单位秒，默认是10秒
        return $ossClient;
    }

    /**
     * Notes: 分片上传
     * @param $ossClient
     * @param $uploadAddress
     * @param $localFile
     * @return mixed
     */
    public function multipartUploadFile($ossClient, $uploadAddress, $localFile)
    {
        return $ossClient->multiuploadFile($uploadAddress['Bucket'], $uploadAddress['FileName'], $localFile);
    }

    /**
     *上传视频转码和水印接口
     * @param $file 文件流
     *author:tangfen
     *date:$ct
     */
    public function transcodingVideo($file){
        $videoInfo = saveFile($file);//先上传到本地
        $localFile = $videoInfo['tempPath'];//上传文件的绝对路径
        $url = explode('/', $videoInfo['fileName']);//视频名称
        $request = Vod::v20170321()->createUploadVideo();
        $request->withFileName($url[1]);//视频源文件名
        $request->withTitle('恒盛时代科技');//标题，UTF8,128大小
        //自己的转码和水印配置
//        $request->withTemplateGroupId('3929baf311a8679d29ea0f8309e36a98'); //转码模板组ID 可设置水印等等  (后台添加转码模板后的ID) 为空时默认不转码(转码转高清等等)   (可设置水印等等)
//        $request->withStorageLocation('outin-9c44c41d505411ec952c00163e1c35d5.oss-cn-shanghai.aliyuncs.com'); //存储地址  后台的添加的存储地址，为空时为后台默认的存储地址  outin-9c44c41d505411ec952c00163e1c35d5.oss-cn-shanghai.aliyuncs.com
        $request->withTemplateGroupId('9ac4a3e64d9060dc463307a213f5b6bf'); //转码模板组ID 可设置水印等等  (后台添加转码模板后的ID) 为空时默认不转码(转码转高清等等)   (可设置水印等等)
        $request->withStorageLocation('outin-6369d3bb50e711ec857e00163e1c60dc.oss-cn-shanghai.aliyuncs.com'); //存储地址  后台的添加的存储地址，为空时为后台默认的存储地址  outin-9c44c41d505411ec952c00163e1c35d5.oss-cn-shanghai.aliyuncs.com
        $result = $request->request();
        $videoId = $result->VideoId;//视频id
        try {
            $uploadAddress = json_decode(base64_decode($result->UploadAddress), true);
            $uploadAuth = json_decode(base64_decode($result->UploadAuth), true);
            $ossClient = self::initOssClient($uploadAuth, $uploadAddress);
            $uploadVideoInfo = self::multipartUploadFile($ossClient, $uploadAddress, $localFile);//上传视频
            $uploadVideoInfo['video_id'] = $videoId;
            return $uploadVideoInfo;
           } catch (ClientException $exception) {
                  return 1;//错误   echo $exception->getMessage() . PHP_EOL;
        }
    }

    /**
     * 单独上传视频检测和智能审核接口
     * Notes: 上传本地视频-点播转码-智能审核
     * $video(必须) 本地上传的文件流 $video = $request->file('video');
     * $title (必须) 视频标题
     * $description   视频描述,utf-8
     *$coverURL  封面url
     *$cateId 分类id
     *$tags 标签 逗号 隔开   a,b
     *$templateGroupId  转码模板组ID 填写后台添加的转码id就行
     *$storageLocation    存储地址 默认  outin-9c44c41d505411ec952c00163e1c35d5.oss-cn-shanghai.aliyuncs.com
     *
     * @param $data
     */
    public function localUploadLocalVideo($video, $title, $description = '', $coverURL = '', $cateId = '', $tags = '', $templateGroupId = '3bb7b379d1153a85a9eeba8af500fa99', $storageLocation = '')
    {
        if (empty($video) || empty($title)) {
            return false;
        }
        $videoInfo = saveFile($video);//先上传到本地
        $localFile = $videoInfo['tempPath'];//上传文件的绝对路径
        $url = explode('/', $videoInfo['fileName']);//视频名称
        $request = Vod::v20170321()->createUploadVideo();
        $request->withTitle($title);//标题，UTF8,128大小
        $request->withFileName($url[1]);//视频源文件名

        $request->withDescription($description);//描述,utf-8
        $request->withCoverURL($coverURL);//封面url
        $request->withCateId($cateId); //分类id
        $request->withTags($tags);      //标签，隔开
        $request->withTemplateGroupId($templateGroupId); //转码模板组ID (后台添加转码模板后的ID) 为空时默认不转码(转码转高清等等)
        $request->withStorageLocation($storageLocation); //存储地址  后台的添加的存储地址，为空时为后台默认的存储地址  outin-9c44c41d505411ec952c00163e1c35d5.oss-cn-shanghai.aliyuncs.com
        $result = $request->request();

        $videoId = $result->VideoId;

        $uploadAddress = json_decode(base64_decode($result->UploadAddress), true);
        $uploadAuth = json_decode(base64_decode($result->UploadAuth), true);
        $ossClient = self::initOssClient($uploadAuth, $uploadAddress);
        $uploadVideoInfo = self::multipartUploadFile($ossClient, $uploadAddress, $localFile);//上传视频

        //提交智能审核作业
        $videoUrl = $uploadVideoInfo['info']['url'];//返回的视频地址
        $taskId = $this->submitAIMediaAuditJob( $videoUrl,2);    //开启注释就行
        $data = [
            'video_id' => $videoId,  //视频ID
            'task_id' => $taskId  //视频检测任务ID
        ];
        return array("status" => 1, "data" => $data);
    }

    /**
     * 提交智能审核作业  callback 自动异步回调结果通知地址
     * $videoUrl 返回的视频/图片地址
     * $videoId  返回的视频/图片ID
     * scenes：检测场景，支持指定多个场景。 porn：图片智能鉴黄,terrorism：图片暴恐涉政
     * $type 图片1，视频2
     */
    public function submitAIMediaAuditJob($fileUrl,$type=1)
    {
        if (empty($fileUrl)) {
            return false;
        }
        try {
            AlibabaCloud::accessKeyClient($this->accessKeyId, $this->accessKeySecret)
                ->regionId('cn-hangzhou')
                ->asDefaultClient();
            $task1 = array(
                'url' => $fileUrl,
            );
            $ranDom = randomnumber();
            // scenes：检测场景，支持指定多个场景。
            // callback、seed：用于回调通知，可选参数。
            if ($type == 1) {//图片提交智能审核
                $result = Green::v20180509()->ImageAsyncScan()
                    ->body(json_encode(array("tasks" => array($task1),
                        "scenes" => array("porn", "terrorism"),//porn：图片智能鉴黄,terrorism：图片暴恐涉政
                        'callback' => '',   //自动异步回调结果通知地址
                        'seed' => $ranDom)))
                    ->request();

            } else {//视频提交智能审核
                $result = Green::v20180509()->videoAsyncScan()
                    ->body(json_encode(array("tasks" => array($task1),
                        "scenes" => array("porn", "terrorism"),//porn：视频智能鉴黄,terrorism：视频暴恐涉政
                        'callback' => '',   //自动异步回调结果通知地址
                        'seed' => $ranDom)))
                    ->request();
            }

            $data = $result->toArray();
            return $data['data'][0]['taskId'];
        } catch (ClientException $exception) {
            echo $exception->getMessage() . PHP_EOL;
        } catch (ServerException $exception) {
            echo $exception->getMessage() . PHP_EOL;
            echo $exception->getErrorCode() . PHP_EOL;
            echo $exception->getRequestId() . PHP_EOL;
            echo $exception->getErrorMessage() . PHP_EOL;
        }
    }

    /**
     * 提交文本智能审核  直接返回检测的结果，不需要同步或者异步查询
     * scenes：检测场景，支持指定多个场景。 porn：图片智能鉴黄,terrorism：图片暴恐涉政
     * $content 检查的文本
     */
    public function submitTextAIMediaAuditJob($content)
    {
        if (empty($content)) {
            return false;
        }
        try {
            AlibabaCloud::accessKeyClient($this->accessKeyId, $this->accessKeySecret)
                ->regionId('cn-shanghai')
                ->asDefaultClient();
            $task1 = array(
                'content' => $content,
            );
            /**
             * 文本垃圾检测：antispam。
             **/
            $result = Green::v20180509()->textScan()
                ->body(json_encode(array('tasks' => array($task1),
                    'scenes' => array('antispam')
                  )))
                ->request();
            $data = $result->toArray();
            return $data;
//            return $data['data'][0]['taskId'];
        } catch (ClientException $exception) {
            return 1;   //echo $exception->getMessage() . PHP_EOL;  错误
        } catch (ServerException $exception) {
            echo $exception->getMessage() . PHP_EOL;
            echo $exception->getErrorCode() . PHP_EOL;
            echo $exception->getRequestId() . PHP_EOL;
            echo $exception->getErrorMessage() . PHP_EOL;
        }
    }


    /**
     * 手动查询视频异步检测结果
     * @param $taskId 视频检测任务ID   智能审核延迟5s才能出结果 （提交检测和查询检测结果需要间隔5s左右）
     * @return bool  https://www.alibabacloud.com/help/zh/doc-detail/53414.htm?spm=a2c63.p38356.0.0.5b6943f6t9DT70#section-qyw-h54-w2b  看查看错误状态码
     * $type 1 图片  2视频
     */
    public function getAIMediaAuditJobInfo($taskId, $type = 1)
    {
        if (empty($taskId)) {
            return false;
        }
        try {
            AlibabaCloud::accessKeyClient($this->accessKeyId, $this->accessKeySecret)
                ->regionId('cn-shanghai')
                ->asDefaultClient();
            switch ($type) {
                case 1://图片
                    $result = Green::v20180509()->ImageAsyncScanResults()
                        ->body(json_encode(array($taskId)))
                        ->request();
                    break;
                case 2://视频
                    $result = Green::v20180509()->videoAsyncScanResults()
                        ->body(json_encode(array($taskId)))
                        ->request();
                    break;
                default:
            }
            $data = $result->toArray();
            return $data;
        } catch (ClientException $exception) {
            return 1;//失败  echo $exception->getMessage() . PHP_EOL;
        } catch (ServerException $exception) {
            echo $exception->getMessage() . PHP_EOL;
            echo $exception->getErrorCode() . PHP_EOL;
            echo $exception->getRequestId() . PHP_EOL;
            echo $exception->getErrorMessage() . PHP_EOL;
        }
    }

    /**
     *获取转码和水印后的视频播放地址
     * 获取转码和水印后的视频详细信息(处理后的视频播放地址）会延迟5s  （上次视频成功之后不能马上获取）
     * $videoId 上传返回的视频id
     *author:tangfen
     *date:$ct
     */
    public function getVideoPlayUrl($videoId,$timeout='36000'){
        if (empty($videoId)) {
            return false;
        }
        try {
            $request =  Vod::v20170321()->GetPlayInfo();
            $request->setVideoId($videoId);
            $request->setAuthTimeout($timeout);
            $result = $request->request();
            return $result->toArray();
        }catch (ClientException $exception) {
               return 'error';
        }
    }
}

